package apobates.gui.formatter.tree;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TreeItem;
import java.util.function.BiPredicate;
/**
 * JavaFx TreeItem 搜索工具
 */
public class JsonNodeTreeSearcher {
    // searchForm
    // 表达式
    // 目标
    private final BiPredicate<SearchNodeForm,JsonNodeItem> predicate;
    private ObservableList<TreeItem<JsonNodeItem>> resultData = FXCollections.observableArrayList();
    public JsonNodeTreeSearcher(BiPredicate<SearchNodeForm,JsonNodeItem> predicate){
        this.predicate = predicate;
    }

    public JsonNodeTreeSearcher(){
        this.predicate = (SearchNodeForm form,JsonNodeItem item)->{
            if(null==item){
                return false;
            }
            if(form.getName() !=null && form.getValue() !=null && !form.getName().isEmpty() && !form.getValue().isEmpty()){
                if(item.getName().indexOf(form.getName())!=-1 && (item.getValue().indexOf(form.getValue())!=-1 || item.getValue().equals(form.getValue()))){
                    // System.out.println(String.format("[JTC][4.2.1]search node: %s has word: %s; value: %s has word: %s @index: %d", item.getName(), name, item.getValue(), value, index));
                    return true;
                }
            }
            if(form.getName() !=null && !form.getName().isEmpty() && (form.getValue() ==null || form.getValue().isEmpty())){
                if(item.getName().indexOf(form.getName())!=-1){
                    // System.out.println(String.format("[JTC][4.2.2]search node: %s has word: %s @index: %d", item.getName(), name, index));
                    return true;
                }
            }
            return false;
        };
    }
    public void search(TreeItem<JsonNodeItem> node, SearchNodeForm form){
        this.resultData.clear();
        searchNode(form, node);
    }

    public ObservableList<TreeItem<JsonNodeItem>> getResultData() {
        return resultData;
    }

    private void matchTreeItem(TreeItem<JsonNodeItem> node, SearchNodeForm form){
        if(this.predicate.test(form, node.getValue())){
            // 在不展开全部节点时为:-1
            this.resultData.add(node);
        }
    }


    // s://builtin.com/software-engineering-perspectives/tree-traversal
    // s://www.educba.com/tree-traversal-java/
    private void searchNode(SearchNodeForm form, TreeItem<JsonNodeItem> node){
        // System.out.println("[JTC][4.1]search action node:");
        if(null == node){
            // System.out.println("[JTC][4.1.1]node is null");
            return;
        }
        if(node.isLeaf()){
            // System.out.println("[JTC][4.1.2]node is leaf:"+node.getValue().getName());
            this.matchTreeItem(node, form);
        }else{
            if(node.getChildren().size()>0) {
                // System.out.println("[JTC][4.1.3]node has children:"+node.getValue().getName());
                for (TreeItem<JsonNodeItem> curNode : node.getChildren()) {
                    // System.out.println("[JTC][4.1.4]node is index:" + curNode.getValue().getName());
                    searchNode(form, curNode);
                }
            } else {
                // System.out.println("[JTC][4.1.5]node is guer:"+node.getValue().getName());
                this.matchTreeItem(node, form);
            }
        }
    }
}
